package ci.web.codec;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.cors.CorsConfig;
import io.netty.handler.codec.http.cors.CorsHandler;
import io.netty.handler.ssl.SslContext;

import java.util.ArrayList;

/**
 * 
 * @author zhh
 */
public class WebChannelIniter extends ChannelInitializer<Channel> {

    private int maxMsgSize;
    private ChannelHandler handler;
    private CorsConfig corsConfig;
    private HostHandler hostHandler;
    
    public SslContext ssl;
    
    /**
     * 
     * @param maxMsgSize    消息最大限制字节数
     * @param alowHosts     允许哪些域名访问
     * @param corsOrigins   cors配置
     * @param msgHandler    消息Handler
     */
    public WebChannelIniter(int maxMsgSize, String alowHosts, String corsOrigins, ChannelHandler msgHandler){
        this.maxMsgSize = maxMsgSize;
        this.handler = msgHandler;
        this.corsConfig = toCorsConfig(corsOrigins);
        this.hostHandler = HostHandler.make(alowHosts);
    }
    private CorsConfig toCorsConfig(String corsOrigins) {
        if(corsOrigins==null){
            return null;
        }
        corsOrigins = corsOrigins.trim();
        if(corsOrigins.isEmpty()){
            return null;
        }
        if(corsOrigins.equals("*")){
            return CorsConfig.withAnyOrigin().build();
        }
        String[] arr = corsOrigins.split(";");
        ArrayList<String> list = new ArrayList<String>();
        for(String o : arr){
            o = o.trim();
            if(o.isEmpty()==false){
                list.add(o);
            }
        }
        if(list.isEmpty()){
            return CorsConfig.withAnyOrigin().build();
        }else{
            return CorsConfig.withOrigins(list.toArray(new String[list.size()])).build();
        }
    }
    public WebChannelIniter(ChannelHandler webHandler){
        this(1024*1024, null, "*", webHandler);
    }
    
    @Override
    protected void initChannel(Channel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        if(ssl!=null){
            pipeline.addLast(ssl.newHandler(channel.alloc()));
        }
        pipeline.addLast("decoder", new HttpRequestDecoder());
        if(hostHandler!=null){
            pipeline.addLast("hosts", hostHandler);
        }
        pipeline.addLast("aggregator", new HttpObjectAggregator(maxMsgSize));
        pipeline.addLast("encoder", new HttpResponseEncoder());
        if(corsConfig!=null){
            pipeline.addLast("cors", new CorsHandler(corsConfig));
        }
        if(handler instanceof CiHttpWebSocketHandler){
            pipeline.addLast("encoder-websocket", new WebSocketDataEncoder());
        }
        pipeline.addLast("handler", handler);
    }
}
